package org.example.aop;

import com.sun.org.apache.xpath.internal.objects.XObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.example.annotations.ProcessInfo;
import org.example.entity.ProcessLog;
import org.example.mapper.ProcessLogMapper;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Date;

@Component
@Aspect
public class ProcessAdvisor {

    private ProcessLogMapper processLogMapper;

    public ProcessAdvisor(ProcessLogMapper processLogMapper) {
        this.processLogMapper = processLogMapper;
    }

    @Around("@annotation(org.example.annotations.ProcessInfo)")
    public Object round(ProceedingJoinPoint pjp){
        //获取方法
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();

        //获取调用的目标方法的方法名
        String methodName = methodSignature.getName();

        //获取反射对应的方法
        Method method = methodSignature.getMethod();

        // method.getDeclaringClass().getName() 拿到方法对应的全类名
        String className = method.getDeclaringClass().getName();

        //获取方法头顶的@ProcessInfo注解
        ProcessInfo declaredAnnotation = method.getDeclaredAnnotation(ProcessInfo.class);

        //获取到@ProcessInfo注解
        String processInfo = declaredAnnotation.value();

        //获取方法的参数信息和参数名
        Parameter[] parameters = method.getParameters();

        StringBuffer paramsInfo = new StringBuffer();

        if (null != parameters && parameters.length>0 ){
            Object[] args = pjp.getArgs();

            for (int i=0;i<parameters.length;i++){
                Parameter p = parameters[i];

                paramsInfo.append(p.getName() + "--" + args[i] + ";");
            }
        }

        ProcessLog processLog=new ProcessLog();
        processLog.setUserId(2);
        processLog.setClassName(className);
        processLog.setMethodName(methodName);
        processLog.setProcessInfo(processInfo);
        processLog.setParamsInfo(paramsInfo.toString());
        processLog.setCreateTime(new Date());

        processLogMapper.insert(processLog);

        Object proceed =null;

        try {
             proceed   = pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }


        return proceed;
    }
}
